package com.qiniu.pili.droid.rtcstreaming.demo.main;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.display.DisplayManager;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.qiniu.pili.droid.rtcstreaming.RTCConferenceOptions;
import com.qiniu.pili.droid.rtcstreaming.RTCStreamingManager;
import com.qiniu.pili.droid.rtcstreaming.demo.R;
import com.qiniu.pili.droid.rtcstreaming.demo.test.AudioCapturer;
import com.qiniu.pili.droid.rtcstreaming.demo.test.CameraPreview;
import com.qiniu.pili.droid.streaming.AVCodecType;
import com.qiniu.pili.droid.streaming.StreamingProfile;
import com.qiniu.pili.droid.streaming.av.common.PLFourCC;

import java.nio.ByteBuffer;

/**
 * 主播activity
 *
 * @author Leo
 *         created at 2018/1/23 下午4:58
 */
public class AnchorActivity extends AppCompatActivity implements View.OnClickListener {

    private RTCStreamingManager mStreamingManager;
    private FrameLayout mFrameLayout;
    private Button mAddConference;
    private Button mQuitConference;
    private Button mPush;
    private Camera mCamera;
    private CameraPreview mPreview;
    private ProgressDialog mProgressDialog;
    private StreamingProfile mStreamingProfile;
    private MediaProjectionManager mMediaProjectionManager;
    private static final String TAG = "Leo";
    private int mResultCode;
    private Intent mData;
    private MediaProjection mMediaProjection;
    private ImageReader mImageReader;
    private byte[] lastFrame;
    private AudioCapturer mAudioCapturer;
    private StreamingUtils mStreamingUtils;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_anchor);
        //获取 MediaProjectionManager 服务
        mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        initView();
        initStream();
        initCamera();
        mStreamingUtils = StreamingUtils.getInstance();
        mStreamingUtils.init(this,RecorderConstant.anchor);
    }

    /**
     * 初始化相机
     *
     * @author Leo
     * created at 2018/1/23 下午5:09
     */
    private void initCamera() {
        //开启相机
        if (checkCameraHardware(this)) {
            // Create an instance of Camera
            mCamera = getCameraInstance();
            // Create our Preview view and set it as the content of our activity.
            mPreview = new CameraPreview(this, mCamera);
            mFrameLayout.addView(mPreview);
        }


    }

    /**
     * 初始化七牛云sdk
     *
     * @author Leo
     * created at 2018/1/23 下午5:07
     */
    private void initStream() {
        RTCStreamingManager.init(getApplicationContext());
        mStreamingManager = new RTCStreamingManager(this, AVCodecType.SW_VIDEO_WITH_SW_AUDIO_CODEC);
        //2.连麦参数设置
        RTCConferenceOptions options = new RTCConferenceOptions();
        options.setVideoEncodingSizeRatio(RTCConferenceOptions.VIDEO_ENCODING_SIZE_RATIO.RATIO_16_9);
        options.setVideoEncodingSizeLevel(RTCConferenceOptions.VIDEO_ENCODING_SIZE_HEIGHT_720);
        options.setVideoBitrateRange(300 * 1000, 800 * 1000);
        // 15 fps is enough
        options.setVideoEncodingFps(15);
        //3.主播配置推流参数
        mStreamingProfile = new StreamingProfile();
        mStreamingProfile
                .setVideoQuality(StreamingProfile.VIDEO_QUALITY_HIGH2)//视频流
                .setAudioQuality(StreamingProfile.AUDIO_QUALITY_HIGH1)
                .setEncoderRCMode(StreamingProfile.EncoderRCModes.QUALITY_PRIORITY)
                .setEncodingOrientation(StreamingProfile.ENCODING_ORIENTATION.PORT)
                .setPreferredVideoEncodingSize(Constant.width, Constant.height) // 配置推流的尺寸，建议与连麦尺寸一致
                .setYuvFilterMode(StreamingProfile.YuvFilterMode.Linear);

        mStreamingManager.setConferenceOptions(options);

        //5.prepare完成配置
        mStreamingManager.prepare(mStreamingProfile);

    }


    private void initView() {
        mAddConference = (Button) findViewById(R.id.add_conference);
        mQuitConference = (Button) findViewById(R.id.quit_conference);
        mPush = (Button) findViewById(R.id.push);
        mFrameLayout = (FrameLayout) findViewById(R.id.camera_preview);
        mPush.setOnClickListener(this);
        mAddConference.setOnClickListener(this);
        mQuitConference.setOnClickListener(this);
        mPush.setOnClickListener(this);
        //加载dialog
        mProgressDialog = new ProgressDialog(this);
        mAudioCapturer = new AudioCapturer();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.add_conference:
                mStreamingUtils.showDialog("正在加入连麦。。。");
                mStreamingUtils.setRoomId(Constant.roomId);
                mStreamingUtils.setUserId("Leo");
                mStreamingUtils.setRoomToken(Constant.roomToken);
                mStreamingUtils.inputAudioFrame();
                break;
            case R.id.quit_conference:
                mStreamingUtils.stopConference();
//                quitConference();
                break;
            case R.id.push:
                mStreamingUtils.showDialog("正在开启直播。。。");
                push();
                break;
        }
    }

    /**
     * 推流
     *
     * @author Leo
     * created at 2018/1/23 下午5:08
     */
    private void push() {
        startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), Constant.SCREEN_SHOT);
    }






    /**
     * 提示信息
     *
     * @author Leo
     * created at 2018/1/23 下午5:24
     */
    private void showToast(String s) {
        Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
    }



    //------------------------ 验证截屏是否能截到SurfaceView的数据（通过相机来验证）  start--------------------------
    private boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }

    public static Camera getCameraInstance() {
        // getNumberOfCameras()-1. 2个  0代表后置（默认） 1代表前置
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

    //------------------------ end --------------------------


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {



            mResultCode = resultCode;
            mData = data;
            setUpMediaProjection();
            setUpVirtualDisplay();

            new Thread() {
                @Override
                public void run() {
                    SystemClock.sleep(1000);
                    while (true) {
                        try {
                            startCapture();
                        } catch (Exception e) {
                            Log.e(TAG, "run: " + e.getMessage());
                        }
                        SystemClock.sleep(40);
                    }
                }
            }.start();
        }
    }

    private void setUpVirtualDisplay() {
        mImageReader = ImageReader.newInstance(Constant.width, Constant.height, PixelFormat.RGBA_8888, 24);
        mMediaProjection.createVirtualDisplay("ScreenShot",
                Constant.width, Constant.height, Constant.dpi,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mImageReader.getSurface(), null, null);
    }

    private void setUpMediaProjection() {
        mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, mData);
    }

    /**
     * 截屏
     *
     * @author Leo
     * created at 2018/1/23 下午5:15
     */
    private void startCapture() {
        Image image = mImageReader.acquireLatestImage();

        byte[] nv21Bytes;
        if (image == null) {
            if (lastFrame != null) {
                nv21Bytes = lastFrame;
            } else {
                return;
            }
        } else {
            int width = image.getWidth();
            int height = image.getHeight();
            final Image.Plane[] planes = image.getPlanes();
            final ByteBuffer buffer = planes[0].getBuffer();
            int pixelStride = planes[0].getPixelStride();
            int rowStride = planes[0].getRowStride();
            int rowPadding = rowStride - pixelStride * width;
            Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
            bitmap.copyPixelsFromBuffer(buffer);

            if (bitmap != null) {
                //        transformStream();
                nv21Bytes = ConvertData.getNV21(width, height, bitmap);
                lastFrame = nv21Bytes;

                image.close();

                mStreamingUtils.setPublishUrl(Constant.pushUrl);
                mStreamingUtils.inputVideoFrame(nv21Bytes, RecorderConstant.width, RecorderConstant.height, PLFourCC.FOURCC_NV21, System.nanoTime());


            }


        }

    }



    //------------------------ 生命周期 --------------------------

    @Override
    protected void onResume() {
        super.onResume();
        mStreamingUtils.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();

        mStreamingUtils.onPause();
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mStreamingUtils.onDestroy();
    }
}
